home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr48 / 386p_200.zip / 386VIDEO.ASM < prev    next >
Assembly Source File  |  1995-01-12  |  33KB  |  1,026 lines

  1. ; ESSENTIAL VIDEO SERVICES plus
  2. ; the default MCGA/VGA XVD driver
  3. ;
  4. ; WARNING! The current 386video mode supports ONLY 320x200 graphics modes
  5. ; with scanline=320 and screen buffer as wide as you can fit it into ram.
  6. ;
  7. ; If you want higher screen resolutions you will have to
  8. ; modify the 386video management routines
  9. ; (the XVD video drivers DO SUPPORT higher screen resolutions
  10. ;  and "linear aperture" mapping, but the current the 386video module does not
  11. ;  use these capabilities).
  12. ;
  13. ; The reason of this is that i'm working on a 320x200 thing
  14. ; and don't have enough time to work on a "full power" 386video
  15. ; with slower mode 320x200 functions (you know, keeping track of
  16. ; video pages boundaries adds cpu overhead)
  17. ;
  18. ; If you want to support higher resolutions just update the 386video
  19. ; mode initialization,touchmapping and pageflipping routines.
  20. ; Look into genflip0.asm to have an idea how >64k pageflipping works.
  21.  
  22. ; If you want to see how to code an XVD "external" driver look into
  23. ; the chip450.asm source file
  24.  
  25. ; N.B.  video page = a 64k block of video memory
  26. ;       display buffer = a sequence of video pages describing the current
  27. ;                        image being displayed (it is located into video ram)
  28. ;       screen buffer  = big bitmap CONTAINING a COPY of the display buffer
  29. ;                        (usually you set the screen buffer bigger than the
  30. ;                         display buffer to support "sprites getting in/out
  31. ;                         of the screen border" by simply blitting them
  32. ;                         on the bigger screen buffer and then copying
  33. ;                         only the "visible" portion of it to display buffer)
  34. ;                        usually located in RAM
  35.  
  36. .386P
  37. code32 segment para public use32
  38.        assume cs:code32,ds:code32
  39.        
  40. include 386power.inc
  41. include 386file.inc
  42. include 386sys.inc
  43. include headxvd.inc
  44.         public _ScrBase,_RowStart
  45.             align dword
  46.  
  47. MAXLINES = 1024
  48.  
  49. ; index of row start offsets from base of display screen
  50. ; maximum vertical resolution is 1024 lines
  51. _RowStart   dd 0
  52.             dd MAXLINES dup(0)
  53.  
  54. ; Disp values are for the DISPlayed window
  55. ; Scr values are for the display page buffer           
  56.             public _DispX,_DispY,_ScrX,_ScrY,_VDispX,_VDispY,_XSquare,_YSquare
  57.             public _XVDTotRam,_XVDVModes
  58.  
  59.                  ; here starts the XVD driver data table
  60.                  ; every XVD driver uses to get/pass information to
  61.                  ; the 386video module
  62. _XVDTable        dd 0 ; card subtype id
  63. _XVDCMode        dd 0 ; last video mode you tried to set
  64. _XVDVPages       dd 1 ; available 64k units in current mode
  65. _XVDVModes       dd 011b ; support for textmode 80x25 and 320x200
  66. _XVDScanline     dd 320  ; lenght in bytes of a display scanline
  67. _XVDAperture     dd 0 ; aperture base address
  68. _XVDASize        dd 0 ; aperture region size (0 = no aperture)
  69. _XSquare         dd 32    ; _XSquare/_YSquare = pixel aspect ratio
  70. _YSquare         dd 24    ; (set by driver init code)
  71. _XVDTotRam       dd 1     ; total ram on video board in 64k units
  72. _DispX           dd 0  ; Display X resolution
  73. _DispY           dd 0  ;   "     Y    "
  74.                  ; end of XVD driver table
  75.  
  76. _ScrX            dd 0  ; Screen buffer X resolution
  77.                        ; X range = 0...(_ScrX-1)
  78. _ScrY            dd 0  ; Screen buffer Y resolution
  79.                        ; Y range = 0...(_ScrY-1)
  80.  
  81. _VDispX          dd 0  ; Visible Display Window X coord inside screen buffer
  82. _VDispY          dd 0  ; Visible Display Window Y coord inside screen buffer
  83.                        ; (_VDispX,_VDispY) = upper left pixel to show
  84. ODispX           dd 0  ; previous values for VDispX,VDispY
  85. ODispY           dd 0  ;
  86.  
  87. SCRSIZE          dd 0
  88.                 public _ScrSD
  89. _ScrSD           dd 0 ;screen size in dwords (useful to some routines)
  90. DSKID            dd 0
  91.  
  92. XWID = 320
  93. YHEI = 200
  94.  
  95. CHUNKSIZE dd 1
  96.         ;top position where a display buffer can start
  97. CHUNKTOP  dd 1
  98.         ; start position of current display buffer
  99. THISCHUNK dd 0
  100.  
  101. _ScrBase    dd 0 ;base of buffered display page
  102.                  ; (changed at every _PageFlip0 if multiple display pages on)
  103. VScrBase    dd 0 ;base of visible window
  104.  ViewBase   dd 0 ;base of viewable display page
  105.                  ; (changed at every _PageFlip0 if multiple display pages on)
  106.  Physbase   dd 0 ;display buffer address
  107.                  ; (used only to store "linear aperture" position)
  108. _XVDBase    dd 0 ;"external" driver base address
  109.  
  110.         align dword
  111. ; the three palette functions are hooked directly to their XGE entry points
  112. ; the other are called indirectly
  113.  
  114. _XVDBiosCheck    dd offset CheckXVD ; returns carry clear if video bios is present
  115. _XVDChipSetCheck dd offset CheckXVD ; returns carry clear is chipset is present
  116.                  ; Currently both of these must be successful
  117.                  ; to "get access" to the graphics extensions.
  118.                  ; A future XGE release will try to use VESA functions
  119.                  ; to set the video mode if _XXVDBiosCheck fails
  120.                  ; and then if _XVDChipSetCheck is successful
  121.                  ; it will "unlock" the extensions thtu direct chipset access.
  122.                  ;
  123.                  ; To use "extended" multi-page mode 13h you only have
  124.                  ; to check for the chipset (the bios entry is the same
  125.                  ; for all boards)
  126.                  ;
  127. _XVDMode         dd offset XVDMode
  128.                  ; Set video mode , called by _SetXVDMode
  129.                  ; eax=requested video mode
  130.                  ; edi=driver table, ebp= driver base
  131.  
  132. _XVDPage         dd offset XVDPage
  133.                  ; changes accessible video block
  134.                  ; in: eax= video block to access
  135.                  ; out: edi=linear address of block start
  136. _XVDVisible      dd offset XVDVisible
  137.                  ; set new visible display buffer staring block
  138.                  ; eax = video block
  139.  
  140. _XVDOpen         dd offset unSupported
  141. _XVDClose        dd offset unSupported
  142. _XVDLineSize     dd offset unSupported
  143. _XVDCardType     dd xcardtype
  144. _XVDProgrammer   dd xprogr
  145. _XVDNotes        dd xnotes
  146.  
  147. easav            dd 0 ; eax buffer for faster operations
  148.  
  149.         align byte
  150. _XVDExternal   db 0   ; tried to load external driver
  151. _XVDGoodDriver db 0   ; found XVD marker at start of driver
  152. _XVDBGood      db 0   ; check for bios OK
  153. _XVDCGood      db 0   ; check for chipset OK
  154.         public _XVDExternal,_XVDGoodDriver,_XVDBGood,_XVDCGood
  155.  
  156. xcardtype db 'VGA/MCGA COMPATIBLE',0
  157. xprogr    db 'Lorenzo Micheletto',0
  158. xnotes    db 'Default XVD driver',0
  159.  
  160. modefailure:
  161.         popad
  162. unSupported:
  163.         stc
  164. XVDVisible:
  165.         ret
  166.  
  167. XVDPage: mov edi,0A0000h
  168.          ret
  169.  
  170. XVDMode: pushad
  171.          mov V86ax,0003h ; text mode
  172.          mov _XVDCMode,0
  173.          or eax,eax
  174.          jz vid_mode
  175.          dec eax
  176.          jne modefailure
  177.          mov  V86ax,0013h ; set graphic mode
  178.          mov _XVDCMode,1
  179. vid_mode:
  180.          mov al,10h
  181.          call _ExecINT
  182.          popad
  183. CheckXVD:
  184.          clc
  185.          ret
  186.  
  187. ;-----------------------------------------------------------------------------
  188. STATUS          = 03DAh ; status register port
  189.  
  190. IS_HVSYNC       = 01
  191. IS_VSYNC        = 08
  192.  
  193. ; palette ports
  194. DACREAD         = 03C7h
  195. DACWRITE        = 03C8h
  196. DACDATA         = 03C9h
  197.  
  198. ;----------------------------------------------------------------------------
  199. ; _Set1Palette        al =  palette entry
  200. ;                    edx = bit 0..7   red
  201. ;                          bit 8..15  green
  202. ;                          bit 16..23 blue 
  203. ;                          bit 24..31 non utilizzati
  204. ;
  205.  
  206.                 public  _Set1Pal
  207. _Set1Pal dd offset XVDSet1Pal
  208.                 
  209. XVDSet1Pal:
  210.                 ; al = palette index
  211.                 ; edx = (XBGR)
  212.                 push eax
  213.                 push ebx
  214.                 mov  ebx,edx
  215.                 push edx
  216.                 shr ebx,2   ; cut out lower bits to get VGA resolution
  217.                 mov     dx,DACWRITE
  218.                 and ebx,003F3F3Fh ; eliminate garbage bits
  219.                 cli
  220.                 out     dx,al  ; index
  221.                 inc     dx
  222.                 mov     al,bl
  223.                 out     dx,al  ; Red
  224.                 mov     al,bh
  225.                 shr     ebx,16
  226.                 out     dx,al  ; Green
  227.                 mov     al,bl
  228.                 out     dx,al  ; Blue
  229.                 sti
  230.                 pop edx
  231.                 pop ebx
  232.                 pop eax
  233.                 ret
  234.  
  235.                 public  _Get1Pal
  236. _Get1Pal dd offset XVDGet1Pal
  237.                 
  238. XVDGet1Pal:
  239.                 ; al = palette index
  240.                 ; edx = (XBGR)
  241.                 push eax
  242.                 ; i choosed to use a BIOS call after some problems
  243.                 ; with my video card
  244.                 mov V86bl,al
  245.                 xor edx,edx
  246.                 mov V86ax,1015h
  247.                 mov al,10h
  248.                 call _ExecINT
  249.                 mov dl,V86cl
  250.                 shl edx,16
  251.                 mov dh,V86ch
  252.                 mov dl,V86dh
  253.                 shl edx,2
  254.                 pop eax
  255.                 ret
  256.  
  257.                 public  _Set256Pal
  258. _Set256Pal  dd offset XVDSet256Pal
  259.  
  260. XVDSet256Pal:
  261.                 ; esi = pointer to 256 palette entries
  262.                 ;       every entry is a dword (XRGB)
  263.                 pushad
  264.                 mov     ecx,256
  265.                 mov     dx,STATUS
  266.                 cli
  267. into_vretrace:
  268.                 in      al,dx
  269.                 test    al,IS_VSYNC
  270.                 jnz     into_vretrace
  271. outof_vretrace:
  272.                 in      al,dx
  273.                 test    al,IS_VSYNC
  274.                 jz      outof_vretrace
  275.                 ; now a full vretrace interval is available
  276.                  
  277.                 mov     dx,DACWRITE
  278.                 xor     eax,eax
  279.                 out     dx,al
  280.                 inc     dx  ; move to DACDATA port
  281.              nextp:
  282.                 mov eax,[esi]
  283.                 shr eax,2           ; 8bit to 6bit color values
  284.                 add esi,4
  285.                 and eax,003F3F3Fh   ;
  286.                 out dx,al ; Red
  287.                 mov al,ah
  288.                 out dx,al ; Green
  289.                 shr eax,16
  290.                 out dx,al ; Blue
  291.                 dec ecx
  292.                 jne nextp
  293.                 sti
  294.                 popad
  295.                 ret
  296.  
  297. ;----------------------------------------------------------------------------
  298.  
  299.              public _SetXVDMode
  300. _SetXVDMode dd offset SetXVDMode
  301. xname  db 'XVD.XVD',0
  302. mem_no db 'Not enough memory for XVD driver data',CR,LF,'$'
  303. no_mem:
  304.         mov _386Return, offset mem_no
  305.         jmp _Exit
  306.  
  307. scr_noo db 'XVD driver: Cannot initialize required video mode',CR,LF,'$'
  308. scr_no_good:
  309.         mov _386Return,offset scr_noo
  310.         jmp _Exit
  311.  
  312. xy_no db 'Wrong screen size, XVD driver does not support it',CR,LF,'$'
  313. xy_no_good:
  314.         mov _386Return, offset xy_no
  315.         jmp _Exit
  316.  
  317. xunload:  mov _HiMemBase,ebp ; restore previous himembase
  318.           mov _XVDBase,0
  319.           jmp driverloaded
  320.         
  321. SetXVDMode:     ; _ScrX,_ScrY,_DispX,_DispY
  322.                 ; must be set before calling this
  323.                 pushad
  324.  
  325.                 cmp _XVDBase,0    ; if already loaded an external driver
  326.                 jne driverloaded  ; then skip this
  327.  
  328.                 mov esi,offset xname ; try to load XVD.XVD
  329.                 call _FLoad          ;
  330.                 jc driverloaded  ; if cannot load driver, use default driver
  331.  
  332.                 mov _XVDExternal,1  ; loaded an external driver
  333.  
  334.                 mov ebp,_HiMemBase  ; base of loaded file
  335.                 cmp byte ptr [ebp],'X'     ;
  336.                 jne driverloaded           ;
  337.                 cmp byte ptr [ebp+1],'V'   ;
  338.                 jne driverloaded           ;
  339.                 cmp byte ptr [ebp+2],'D'   ;
  340.                 jne driverloaded           ;
  341.                 cmp byte ptr [ebp+3],'0'   ;
  342.                 jne driverloaded           ; check 'XVD0' marker
  343.  
  344.                 mov _XVDGoodDriver,1  ; driver header looks good
  345.  
  346.                 mov _XVDBase,ebp
  347.                 add eax,ebp
  348.                 mov _HiMemBase,eax
  349.                 ; check if driver matches the graphics card
  350.                 mov edi,offset _XVDTable
  351.                 mov edx,[ebp+__XVDBiosCheck]
  352.                 add edx,ebp
  353.                 call edx ; check bios
  354.                 jc xunload
  355.  
  356.                 mov _XVDBGood,1    ; bios check looks good
  357.  
  358.                 mov edx,[ebp+__XVDChipSetCheck]
  359.                 add edx,ebp
  360.                 call edx ; check chipset
  361.                 jc xunload
  362.  
  363.                 mov _XVDCGood,1   ; chipset check looks good
  364.                 
  365.                 ; Now LINK all entries to their pointers
  366.                 ; correcting the driver based offsets to code32 base
  367.  
  368.                 mov edx,[ebp+__XVDBiosCheck]
  369.                 add edx,ebp
  370.                 mov _XVDBiosCheck,edx
  371.  
  372.                 mov edx,[ebp+__XVDChipSetCheck]
  373.                 add edx,ebp
  374.                 mov _XVDChipSetCheck,edx
  375.  
  376.                 mov edx,[ebp+__XVDMode]
  377.                 add edx,ebp
  378.                 mov _XVDMode,edx
  379.  
  380.                 mov edx,[ebp+__XVDPage]
  381.                 add edx,ebp
  382.                 mov _XVDPage,edx
  383.  
  384.                 mov edx,[ebp+__XVDVisible]
  385.                 add edx,ebp
  386.                 mov _XVDVisible,edx
  387.  
  388.                 mov edx,[ebp+__XVDOpen]
  389.                 add edx,ebp
  390.                 mov _XVDOpen,edx
  391.  
  392.                 mov edx,[ebp+__XVDClose]
  393.                 add edx,ebp
  394.                 mov _XVDClose,edx
  395.  
  396.                 mov edx,[ebp+__XVDLineSize]
  397.                 add edx,ebp
  398.                 mov _XVDLineSize,edx
  399.  
  400.                 mov edx,[ebp+__XVDSet1Pal]
  401.                 add edx,ebp
  402.                 mov _Set1Pal,edx
  403.  
  404.                 mov edx,[ebp+__XVDSet256Pal]
  405.                 add edx,ebp
  406.                 mov _Set256Pal,edx
  407.  
  408.                 mov edx,[ebp+__XVDGet1Pal]
  409.                 add edx,ebp
  410.                 mov _Get1Pal,edx
  411.  
  412.                 mov edx,[ebp+__XVDCardType]
  413.                 add edx,ebp
  414.                 mov _XVDCardType,edx
  415.  
  416.                 mov edx,[ebp+__XVDProgrammer]
  417.                 add edx,ebp
  418.                 mov _XVDProgrammer,edx
  419.  
  420.                 mov edx,[ebp+__XVDNotes]
  421.                 add edx,ebp
  422.                 mov _XVDNotes,edx
  423.  
  424. driverloaded:
  425.                 ; well, driver is initialized, now we will try
  426.                 ; to set up the required video mode
  427.                 mov eax,_ScrX
  428.                 add eax,3
  429.                 and eax,0FFFFFFFCh  ; round to dword count
  430.                 mov _ScrX,eax
  431.  
  432.                 mov edx,_ScrY
  433.                 mov ecx,_DispX
  434.                 cmp ecx,XWID
  435.                 jne xy_no_good
  436.                 cmp _DispY,YHEI
  437.                 jne xy_no_good
  438.  
  439.                 sub eax,ecx
  440.                 mov DSKID,eax  ; store width difference
  441.  
  442.                 add eax,ecx  ; eax= _ScrX
  443.                 mul edx      ; edx= _ScrY
  444.                 ; eax = screen buffer size in bytes
  445.                 mov ecx,eax
  446.                 shr ecx,2
  447.                 mov SCRSIZE,eax
  448.                 mov _ScrSD,ecx  ;screen buffer size in dwords
  449.  
  450.                 call _GetHiMem
  451.                 jc no_mem
  452.  
  453.                 mov _ScrBase,eax
  454.                 mov VScrBase,eax
  455.                 xor eax,eax
  456.                 mov _VDispX,eax
  457.                 mov _VDispY,eax
  458.                 mov edi,offset _RowStart ; Row offset table 
  459.                 mov ecx,_ScrY            ;
  460.                 mov ebx,_ScrX            ;
  461. iloop:
  462.                 stosd
  463.                 add eax,ebx
  464.                 dec ecx
  465.                 jne iloop
  466.  
  467.                 mov eax,1       ; try to set 320x200 video mode
  468.                 mov CHUNKSIZE,1 ; set screen chunk size
  469.                 mov edi,offset _XVDTable
  470.                 mov ebp,_XVDBase
  471.                 call _XVDMode  ; set display mode
  472.                 jc scr_no_good
  473.  
  474.                 cmp _XVDBase,0   ; if using the integrated driver
  475.                 je  donexvdrelink  ; then skip this
  476.                 ; Now LINK AGAIN all entries to their pointers
  477.                 ; This allows the mode-initialization routine
  478.                 ; to change the values into the XVD device table
  479.                 ; (for example, changing the available video page count
  480.                 ;  if there are bank limits you cannot "run around")
  481.                 ; AND to "select" mode specific routines
  482.                 ; depending of the video-card/graphic-mode combination
  483.  
  484.                 mov edx,[ebp+__XVDBiosCheck]
  485.                 add edx,ebp
  486.                 mov _XVDBiosCheck,edx
  487.  
  488.                 mov edx,[ebp+__XVDChipSetCheck]
  489.                 add edx,ebp
  490.                 mov _XVDChipSetCheck,edx
  491.  
  492.                 mov edx,[ebp+__XVDMode]
  493.                 add edx,ebp
  494.                 mov _XVDMode,edx
  495.  
  496.                 mov edx,[ebp+__XVDPage]
  497.                 add edx,ebp
  498.                 mov _XVDPage,edx
  499.  
  500.                 mov edx,[ebp+__XVDVisible]
  501.                 add edx,ebp
  502.                 mov _XVDVisible,edx
  503.  
  504.                 mov edx,[ebp+__XVDOpen]
  505.                 add edx,ebp
  506.                 mov _XVDOpen,edx
  507.  
  508.                 mov edx,[ebp+__XVDClose]
  509.                 add edx,ebp
  510.                 mov _XVDClose,edx
  511.  
  512.                 mov edx,[ebp+__XVDLineSize]
  513.                 add edx,ebp
  514.                 mov _XVDLineSize,edx
  515.  
  516.                 mov edx,[ebp+__XVDSet1Pal]
  517.                 add edx,ebp
  518.                 mov _Set1Pal,edx
  519.  
  520.                 mov edx,[ebp+__XVDSet256Pal]
  521.                 add edx,ebp
  522.                 mov _Set256Pal,edx
  523.  
  524.                 mov edx,[ebp+__XVDGet1Pal]
  525.                 add edx,ebp
  526.                 mov _Get1Pal,edx
  527.  
  528.                 mov edx,[ebp+__XVDCardType]
  529.                 add edx,ebp
  530.                 mov _XVDCardType,edx
  531.  
  532.                 mov edx,[ebp+__XVDProgrammer]
  533.                 add edx,ebp
  534.                 mov _XVDProgrammer,edx
  535.  
  536.                 mov edx,[ebp+__XVDNotes]
  537.                 add edx,ebp
  538.                 mov _XVDNotes,edx
  539.  
  540.                 ; end of "re-linking"
  541.                 ; now see how much memory is available
  542.                 ; and set the "page switching" limits
  543. donexvdrelink:
  544.                 mov eax,_XVDVPages
  545. goodbank:
  546.                 sub eax,CHUNKSIZE
  547.                 mov CHUNKTOP,eax
  548.                 xor eax,eax ;
  549.                 mov THISCHUNK,eax  ; display buffer base in 64k vram pages
  550.                 call _XVDPage
  551.                 sub edi,_Code32Base  ; store base page frame address
  552.                 mov ViewBase,edi     ;
  553.  
  554. ; ritorna a chi ha chiamato
  555.                 call MakeTouchBlitter ; initialize pageflip things
  556.                 call MakeTouchMap
  557.                 ; insert the "video mode termination code"
  558.                 mov eax, offset RestoreTextMode
  559.                 call _OnExit
  560.                 popad
  561.         ret
  562.         
  563. ;----------------------------------------------------------------------------
  564. ; void RestoreTextMode( void )
  565.  
  566.                 public  _RestoreTextMode
  567. _RestoreTextMode  dd offset RestoreTextMode
  568.  
  569. RestoreTextMode:
  570.                 pushad
  571.                 xor eax,eax
  572.                 call _XVDMode
  573.                 
  574.                 popad
  575.         ret
  576.  
  577.  
  578.  
  579. ;----------------------------------------------------------------------------
  580. ; void DisplayStart(eax= x,edx =y)  SET DISPLAY VIDEO WINDOW POSITION
  581. ;                                   INSIDE DISPLAY PAGE
  582.  
  583.         public _DisplayStart
  584. _DisplayStart   dd offset DisplayStart
  585.  
  586. DisplayStart:
  587.                 ; eax= x_position , edx = y_position
  588.                 push eax
  589.                 mov _VDispX,eax
  590.                 mov _VDispY,edx
  591.                 add eax,_ScrBase
  592.                 add eax,[edx*4+_RowStart]
  593.                 mov VScrBase,eax
  594.                 pop eax
  595.         ret
  596.         
  597. ; SMART PAGE FLIPPING CODE
  598.  
  599.         align dword
  600. TOUCHDSIZE = (3*YHEI)
  601.         
  602. ; touchmap pointers
  603. touch0     dd 0
  604. touch1     dd 0
  605.         align byte
  606. touchfrag db '386Video: TouchMap allocation failed',CR,LF,'$'
  607. tmapfail: mov _386Return,offset touchfrag
  608.           jmp _Exit
  609.  
  610. MakeTouchMap:
  611.         mov eax,((TOUCHDSIZE*2)*4)
  612.         mov ebp,TOUCHDSIZE
  613.         call _GetHiMem
  614.         jc tmapfail
  615.         mov touch0,eax
  616.         lea ecx,[ebp*2]
  617.         mov edi,eax
  618.         lea esi,[eax+ebp*4]
  619.         xor eax,eax
  620.         mov touch1,esi
  621.         rep stosd
  622.         ret
  623.         
  624.         public _TouchBlock
  625. _TouchBlock dd offset TouchBlock
  626.  
  627. TouchBlock:
  628.         ; eax,edx = xstart (dots), ystart(dots)   upper-left position of block
  629.         ; ecx,ebx = xwidth (nudgets), yheight (dots) of touched block in pixels
  630.         ;
  631.         ; N.B. This routine is currently LIMITED TO 320x200 SCREEN RESOLUTION
  632.         ;
  633.         ; HOW TO INTERLEAVE INSTRUCTIONS QUICKLY AND GET FASTER CODE:
  634.         ; a) select TWO indipendent operations to perform
  635.         ; b) subdivide the available registers between the two operations
  636.         ; c) write the code for the two operations
  637.         ; d) INTERLEAVE the instructions composing the two code sequences
  638.         ;    avoiding to "couple together" complex instructions
  639.         ;    BUT KEEP IN SEQUENCE instructions that depends
  640.         ;    from flag status result of previous instruction
  641.         ; e) See the MIPS rating skyrocket when you run the resulting code
  642.         ;    on a 486 or Pentium processor :).
  643.         ; f) Laugh when you think at what happens when somebody tries to
  644.         ;    perform reverse engineering on your interleaved code.
  645.  
  646.         ; some things are hard to interleave
  647.         pushad
  648.         ; other "sequences" can be interleaved pretty quickly
  649.         ; ( identation is used to show the two code sequences)
  650.         ; CALCULATE BLOCK MASKS
  651.         ; ecx,eax,edi
  652.                 ; CALCULATE STARTING POSITION OF POINTERS
  653.                 ; edx,ebp,esi
  654.                 mov esi,eax ; GLUE CODE copy xstart in dots 
  655.         inc ecx ; one more dword to round off 
  656.         shr eax,2 ; dword granularity for start position
  657.                 mov ebp,edx ; GLUE CODE  copy yheight
  658.         add ecx,eax ; last blit position in dwords
  659.                 shr esi,7 ; dword granularity , 32 dword bits onto touchlist item
  660.                 ; == column dword index into touchmap == xstart
  661.                 ; now calc ystart* 12 to get line offset
  662.         mov edi,eax ;  start column in dwords
  663.                 add ebp,esi ; wow! ultra-smart optimization! 
  664.                 ; ebp & esi needs to be multiplied by 4 so ...
  665.                 shl edx,3  ;  ystart*8
  666.         and eax,01Fh ; mask  low  start count
  667.         shr edi,5    ; shift high start count
  668.                 lea esi,[edx+ebp*4] ;  ystart*8+((xstart/128)+ystart)*4
  669.                                     ;  = (xstart/128)*4 + ystart*12
  670.                                     ;  = offset of first dword to touch
  671.                 ; EBP discarded from here
  672.         mov ebp,ecx  ; end column in dwords
  673.                 add esi,touch0 ; START IN DWORDS base+xstart+ystart*12
  674.         ; now interleave the final masking calculations 
  675.         and ecx,01Fh ; mask  low  stop count
  676.         mov edx,-1
  677.         shl edx,cl
  678.         mov ecx,eax ; set new shift counter
  679.         shr ebp,5    ; shift high stop count
  680.         not edx ; invert bits ---> TAIL MASK
  681.         mov eax,-1
  682.         sub ebp,edi  ; WIDTH IN PACKDWORDS 
  683.         shl eax,cl ; HEAD MASK
  684.         mov edi,12
  685.         dec ebp   ; how many PackDwords ?
  686.         jz sidebyside
  687.         jns middlestrip
  688.         ; overlapping
  689.         and eax,edx
  690. overblit:
  691.         or [esi],eax
  692.         add esi,edi
  693.         dec ebx
  694.         je eoverblit
  695.         or [esi],eax
  696.         add esi,edi
  697.         dec ebx
  698.         jne overblit
  699. eoverblit:
  700.         popad 
  701.         ret
  702. sidebyside:
  703.         or [esi],eax
  704.         or [esi+4],edx
  705.         add esi,edi
  706.         dec ebx
  707.         je esidebyside
  708.         or [esi],eax
  709.         or [esi+4],edx
  710.         add esi,edi
  711.         dec ebx
  712.         jne sidebyside
  713. esidebyside:
  714.         popad
  715.         ret
  716. middlestrip:
  717.         or [esi],eax
  718.         mov dword ptr [esi+4],-1        
  719.         or [esi+8],edx
  720.         add esi,edi
  721.         dec ebx
  722.         je emiddlestrip
  723.         or [esi],eax
  724.         mov dword ptr [esi+4],-1        
  725.         or [esi+8],edx
  726.         add esi,edi
  727.         dec ebx
  728.         jne middlestrip
  729. emiddlestrip:
  730.         popad
  731.         ret
  732.  
  733. ;--------------------------------------------------------------------------
  734. ; void cdecl PageFlip(void)
  735. ;
  736.  
  737.           public _PageFlip0
  738. _PageFlip0 dd offset PageFlip0
  739.  
  740.  
  741. PageFlip0: ; ViewBase <-- _ScrBase "brute force"
  742.            ; optimized routine for 320x200 screen resolution
  743.           pushad
  744. rawblit:
  745.           mov ebp,DSKID
  746.           mov esi,VScrBase
  747.           mov eax,THISCHUNK
  748.           mov ebx,(XWID/4)  ; line width in dwords
  749.           add eax,CHUNKSIZE
  750.           cmp eax,CHUNKTOP
  751.           jb  fchunkgood
  752.           xor eax,eax
  753. fchunkgood:
  754.           mov THISCHUNK,eax
  755.           call _XVDPage
  756.           sub edi,_Code32Base
  757.           mov edx,YHEI
  758.           mov ViewBase,edi
  759. fnextruw:
  760.           mov ecx,ebx
  761.           rep movsd
  762.           add esi,ebp
  763.           dec edx
  764.           je fruwend
  765.           ; unroll one step
  766.           mov ecx,ebx
  767.           rep movsd
  768.           add esi,ebp
  769.           dec edx
  770.           jne fnextruw
  771. fruwend:
  772.           mov eax,THISCHUNK  ; set this as the next visible page
  773.           call _XVDVisible   ;
  774.           jmp zapatron
  775.  
  776.           public _PageFlip1
  777. _PageFlip1 dd offset PageFlip1
  778.  
  779. PageFlip1:
  780.           ; ViewBase <-- _ScrBase using TouchMaps
  781.           pushad
  782.           
  783.           mov ecx,_VDispX   ;  test if touchmap are not effective
  784.           mov eax,_VDispY   ;  because of massive screen motion
  785.           cmp ecx,ODispX    ;
  786.           jne rawblit       ;
  787.           cmp eax,ODispY    ;
  788.           jne rawblit       ;
  789.           ; now execute a page update without changing the visible screen
  790.  
  791.           mov ebx,touch0 ; delta pages
  792.           mov ebp,touch1 ;
  793.           
  794.           mov esi,VScrBase
  795.           mov edi,ViewBase
  796.           
  797. blitsome: mov ecx,YHEI
  798.           xor eax,eax
  799. blitdline:
  800.           ; blit first 128 dots          
  801.           mov edx,[ebx]
  802.           or  edx,[ebp]
  803.           mov al,dl
  804.           call [eax*4+touchdown]
  805.           mov al,dh
  806.           shr edx,16
  807.           call [eax*4+touchdown]
  808.           mov al,dl
  809.           shr edx,8
  810.           call [eax*4+touchdown]
  811.           call [edx*4+touchdown]
  812.           ; blit other 128 dots
  813.           mov edx,[ebx+4]
  814.           or  edx,[ebp+4]
  815.           mov al,dl
  816.           call [eax*4+touchdown]
  817.           mov al,dh
  818.           shr edx,16
  819.           call [eax*4+touchdown]
  820.           mov al,dl
  821.           shr edx,8
  822.           call [eax*4+touchdown]
  823.           call [edx*4+touchdown]
  824.           ; blit the last 64 dots
  825.           mov edx,[ebx+8]
  826.           or  edx,[ebp+8]
  827.           mov al,dl
  828.           call [eax*4+touchdown]
  829.           mov al,dh
  830.           add ebx,12
  831.           add ebp,12
  832.           call [eax*4+touchdown]
  833.           add esi,DSKID
  834.           dec ecx
  835.           jne blitdline
  836. zapatron: 
  837.           ; update touchmap pointers & reset current touchmap
  838.           mov ebx,touch0 ; switch delta pages
  839.           mov edi,touch1 ;
  840.           mov touch0,edi ;
  841.           mov touch1,ebx ;
  842.           xor eax,eax
  843.           mov ecx,TOUCHDSIZE
  844.           rep stosd
  845.           ; update old screen pos
  846.           mov edx,_VDispX
  847.           mov eax,_VDispY
  848.           mov ODispX,edx
  849.           mov ODispY,eax
  850.           popad 
  851.           ret
  852.           
  853.           
  854. ; END OF PAGE FLIPPING CODE
  855.  
  856. ; list of pointer to optimized code blitting snippets          
  857. touchdown dd 256 dup(0)
  858.  
  859. WADDESIB = 0C683h
  860. WADDEDIB = 0C783h
  861. BMOVSD   = 0A5h
  862. BRETN    = 0C3h
  863. nocomp   db ' Not enough High Memory for BLIT COMPILER ',CR,LF,'$'
  864. bombed:
  865.         mov _386Return,offset nocomp
  866.         jmp _Exit
  867.         
  868. ; initializes the touchdown list
  869. ; "compiling" the chunk blit code
  870.  
  871. MakeTouchBlitter:
  872.         pushad
  873.         mov edi,_HiMemBase  ; use high memory
  874.         mov esi,_HiMemTop   ;
  875.         sub esi,edi ; available space
  876.         mov ebx,offset touchdown ; pointer to touch blitter table
  877.         xor ecx,ecx ; ecx=0 chunk counter
  878. inflate:
  879.         xor edx,edx ; edx=0 skip counter
  880.         mov [ebx],edi ; store start of this blit code chunk
  881.         mov ebp,8 ; 8 touchbits to evaluate
  882.         add ebx,4 ; next item
  883.         mov eax,ecx
  884. inflatebyte:        
  885.         shr eax,1
  886.         jc  blast
  887.         add edx,4 ; increase skip if don't-touch
  888. inflagain:        
  889.         dec ebp
  890.         jnz inflatebyte
  891.         test edx,edx
  892.         jz notail
  893.         sub esi,6
  894.         jb bombed
  895.         mov word ptr [edi],WADDESIB
  896.         mov [edi+2],dl
  897.         mov word ptr [edi+3],WADDEDIB
  898.         mov [edi+5],dl
  899.         add edi,6
  900. notail:        
  901.         sub esi,1
  902.         js bombed
  903.         mov byte ptr [edi],BRETN
  904.         inc edi
  905.         inc cl
  906.         jnz inflate
  907.         mov _HiMemBase,edi
  908.         popad
  909.         ret
  910.         
  911. blast:
  912.         test edx,edx
  913.         jz noskippy
  914.         sub esi,6
  915.         jb bombed
  916.         mov word ptr [edi],WADDESIB
  917.         mov [edi+2],dl
  918.         mov word ptr [edi+3],WADDEDIB
  919.         mov [edi+5],dl
  920.         add edi,6
  921. noskippy:
  922.         sub esi,1
  923.         js bombed
  924.         mov byte ptr [edi],BMOVSD
  925.         inc edi
  926.         xor edx,edx
  927.         jmp short inflagain
  928.                 
  929.           public _CompFlip
  930. _CompFlip dd offset CompFlip                
  931.  
  932. CompFlip:
  933.         ; Compiles a pageflipping mask or a pageflipping routine
  934.         ; (useful when the portions you have to "refresh" are nearly always
  935.         ;  the same)
  936.         ; to do this you have to pass the base and top pointers
  937.         ; to the heap you want to store the pageflip data on.
  938.         ; BEFORE:
  939.         ; Use _TouchBlock to set the current touchmap as you want
  940.         ; the "compiled pageflipper" will act.
  941.         ; IN:
  942.         ; eax = allocation heap base , edx = allocation heap top
  943.         ; OUT:
  944.         ; IF CARRY CLEAR THEN
  945.         ;    eax = NEW allocation heap base, edx = NEW allocation heap top
  946.         ;    edi = pointer to custom pageflipping data/code
  947.         ; ELSE NOT ENOUGH MEMORY, NOTHING HAPPENED
  948.         push edx
  949.         sub edx,eax
  950.         cmp edx,TOUCHDSIZE
  951.         jb outofmem
  952.         push ecx
  953.         push esi
  954.         mov edi,eax
  955.         mov esi,touch0
  956.         mov ecx,TOUCHDSIZE
  957.         rep movsd
  958.         pop esi
  959.         pop ecx
  960.         pop edx
  961.         xchg edi,eax
  962.         clc
  963.         ret
  964. outofmem:
  965.         pop edx
  966.         stc
  967.         ret        
  968.         
  969. extrn _CustomFlip:dword
  970.         ; Executes a custom pageflipping as compiled from _CompFlip
  971.         ; but doesn't updates the touchmaps
  972.         ; (it is supposed you don't use touchmaps if you want a custom flip)
  973.         ; IN:
  974.         ;    eax= pointer to custom pageflipping data/code      
  975.           pushad
  976.           mov ebx,eax
  977.           mov esi,VScrBase
  978.           mov edi,ViewBase
  979.           mov ecx,_DispY
  980.           xor eax,eax
  981. cblitdline:
  982.           ; blit first 128 dots          
  983.           mov edx,[ebx]
  984.           mov al,dl
  985.           call [eax*4+touchdown]
  986.           mov al,dh
  987.           shr edx,16
  988.           call [eax*4+touchdown]
  989.           mov al,dl
  990.           shr edx,8
  991.           call [eax*4+touchdown]
  992.           call [edx*4+touchdown]
  993.           ; blit other 128 dots
  994.           mov edx,[ebx+4]
  995.           mov al,dl
  996.           call [eax*4+touchdown]
  997.           mov al,dh
  998.           shr edx,16
  999.           call [eax*4+touchdown]
  1000.           mov al,dl
  1001.           shr edx,8
  1002.           call [eax*4+touchdown]
  1003.           call [edx*4+touchdown]
  1004.           ; blit the last 64 dots
  1005.           mov edx,[ebx+8]
  1006.           mov al,dl
  1007.           call [eax*4+touchdown]
  1008.           mov al,dh
  1009.           add ebx,12
  1010.           add ebp,12
  1011.           call [eax*4+touchdown]
  1012.           add esi,DSKID
  1013.           dec ecx
  1014.           jne cblitdline
  1015.           ; update old screen pos
  1016.           mov edx,_VDispX
  1017.           mov eax,_VDispY
  1018.           mov ODispX,edx
  1019.           mov ODispY,eax
  1020.           popad 
  1021.           ret
  1022.                 
  1023. code32  ends
  1024.  
  1025.     END
  1026.